package cn.bincker.csustcj.edu;

import cn.bincker.csustcj.edu.entity.*;
import cn.bincker.csustcj.edu.exception.PlatformException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public interface Platform {
    String MEDIA_TYPE_APPLICATION_JSON = "application/json; charset=utf-8";
    String MEDIA_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded; charset=UTF-8";
    String URL_BASE = "https://csustcj.edu-edu.com.cn";
    String URL_BASE_CWS = "https://cws.edu-edu.com";
    String URL_BASE_EXAM = "https://cjexamnew.edu-edu.com";
    String URL_SIGN_IN = URL_BASE + "/Index/SignIn";
    String URL_LOGIN = URL_BASE + "/Index/Login/";
    String URL_INDEX = URL_BASE + "/StudentSiteNew/StudentSiteIndexNew/IndexNew";
    String URL_GET_MAJOR = URL_BASE + "/StudentSiteNew/StudentSiteIndexNew/GetStuMajor";
    String URL_GET_MSG = URL_BASE + "/InformationManage/MessageManage/GetMsg";
    String URL_CHANGE_MAJOR = URL_BASE + "/StudentSiteNew/StudentSiteIndexNew/ChangeMajor";
    String URL_GET_ALL_MSG = URL_BASE + "/InformationManage/MessageManage/GetMsgAll";
    String URL_GET_CLASS_INFO = URL_BASE + "/StudentSiteNew/StudentSiteIndexNew/GetClassName";
    String URL_GET_STUDENT_INFO = URL_BASE + "/MyMessageNew/StudentInfoGMC_StuNew/GetInfo";
    String URL_ONLINE_LEARNING_NEW_INDEX = URL_BASE + "/MyOnlineCourseNew/OnlineLearningNew/OnlineLearningNewIndex";
    String URL_ONLINE_LEARNING_NEW_COMPARE_TIME = URL_BASE + "/MyOnlineCourseNew/OnlineLearningNew/CompareTime";
    String URL_GET_FACE_CJ_AND_DB_MODE = URL_BASE + "/StudentSiteNew/StudentSiteIndexNew/GetFaceCjAndDbModel";
    String URL_GET_COURSE_URL = URL_BASE + "/MyOnlineCourseNew/OnlineLearningNew/GetCourseUrl";
    String URL_EXIT = URL_BASE + "/StudentSiteNew/StudentSiteIndexNew/Exit";
    String URL_CWS_INDEX = URL_BASE_CWS + "/page/client";
    String URL_FIND_CW_BY_CODE = URL_BASE_CWS + "/client/%s/findCwByCode?userId=%s&clientCode=%s";
    String URL_CATALOGS = URL_BASE_CWS + "/client/catalogs";
    String URL_CATALOG_INFO = URL_BASE_CWS + "/client/catalogInfo/%s";
    String URL_LEARN_RECORD_USER = URL_BASE_CWS + "/client/learnRecord/user?learnRecordId=%s&userId=%s&userName=%s&clientCode=%s&businessLineCode=%s&coursewareCode=%s&coursewareName=%s&catalogId=%s&catalogTitle=%s&videoTime=%s&backUrl=https://csustcj.edu-edu.com.cn/CourseList/LearnReturnUrl/LearnReturnUrlIndex?ename=%s&validTime=0&lastTime=0&accumulativeTime=0";
    String URL_LEARN_RECORD = URL_BASE_CWS + "/client/learnRecords";
    String URL_LEARN_RETURN_URL_INDEX = URL_BASE + "/CourseList/LearnReturnUrl/LearnReturnUrlIndex?ename=%s";
    String URL_SCORE_DETAIL = URL_BASE + "/MyOnlineCourseNew/ScoreDetailListNew/ScoreDetailListNewIndex?type=0&termCourseID=%s";
    String URL_EXAMINATION_INDEX = URL_BASE + "/MyOnlineCourseNew/OnlineLearningNew/StudentSiteNewExIndex?termcourseID=%s&type=2";
    String URL_GET_EXAMINATION_URL = URL_BASE + "/MyOnlineCourseNew/OnlineLearningNew/GetExamUrl_New";
    String URL_BASE_CJE1 = "https://cje1.edu-edu.com";
    String URL_BASE_CJE2 = "https://cje2.edu-edu.com";
    String URL_SUBMIT_EXAMINATION_ANSWER = "/exam/student/exam/myanswer/newSave/%s/%s";
    String URL_SUBMIT_EXAMINATION = "/exam/student/exam/submit/%s";
    String URL_GET_EXAMINATION_ANSWER = "/exam/student/exam/answer/%s";
    String REQUEST_WITH_XML_HTTP_REQUEST = "XMLHttpRequest";
    String REQUEST_WITH_DOCUMENT = "document";

    /**
     * 登录
     */
    void login(String username, String password);

    /**
     * 获取专业列表
     */
    List<Major> getMajors();

    /**
     * 获取消息
     */
    Message getMessage();

    /**
     * 选择专业
     */
    ChangeMajorResult changeMajor(Major major);

    /**
     * 获取所有消息
     */
    List<Message> getAllMessage();

    /**
     * 获取班级信息
     */
    CommonResult getClassInfo();

    /**
     * 获取学生信息
     */
    StudentInfo getStudentInfo();

    /**
     * 获取课程列表
     */
    Map<String,List<Course>> getCourses();

    /**
     * 判断学习时间，进入课程学习前调用
     * @param type 0:课件学习   1:平时作业  2:考试
     */
    CommonResult compareLearnTime(Course course, int type);

    /**
     * 获取课程视频链接
     */
    CommonResult getCourseUrl(Course course);
    void exit();
    OkHttpClient httpClient();
    ObjectMapper objectMapper();

    /**
     * 获取成绩详情
     * @param course 学科
     */
    ScoreDetail getScoreDetail(Course course);

    /**
     * 查找课件
     * @param clientCode 客户端ID
     */
    CourseWare findCourseWareByByCode(Course course, String userId, String clientCode);

    /**
     * 获取课件目录
     * @param courseWare 课件
     * @param userId 用户ID
     * @param clientCode 客户端ID
     */
    List<CourseWareCatalog> getCourseCatalog(CourseWare courseWare, String userId, String clientCode);

    /**
     * 获取课件目录信息
     * @param courseWare 课件目录
     * @param userId 用户ID
     * @param clientCode 客户端ID
     */
    CourseCatalogInfo getCourseCatalogInfo(CourseWareCatalog courseWare, String userId, String clientCode);

    /**
     * 获取学习记录
     * @param userId 用户ID
     * @param userName 用户名称
     * @param clientCode 客户端ID
     * @param courseWare 课件
     * @param catalogInfo 课件信息
     */
    LearnRecord getUserLearnRecord(String userId, String userName, String clientCode, CourseWare courseWare, CourseCatalogInfo catalogInfo);

    /**
     * 提交学习记录
     * @param learnRecord 学习记录
     */
    LearnRecord postLearnRecord(LearnRecord learnRecord);

    /**
     * 提交学习记录修改
     * @param learnRecord 学习记录
     */
    LearnRecord putLearnRecord(LearnRecord learnRecord);

    /**
     * 同步学习记录
     * @param username 用户名
     * @param learnRecord 学习记录
     */
    ResponseResult<?> syncLearnRecord(String username, LearnRecord learnRecord);

    /**
     * 获取平时作业列表
     * @param course 学科
     */
    List<Examination> getExaminationList(Course course);

    /**
     * 获取平时作业考试URL
     * @param examination
     */
    CommonResult getExaminationUrl(Examination examination, boolean record);

    /**
     * 查看考试记录
     * @param examination
     */
    List<ExaminationRecord> getExaminationRecord(Examination examination);

    /**
     * 考试
     */
    void doExamination(Examination examination, String startExaminationUrl, String viewAnswerUrl);

    default Request.Builder buildRequest(String url) {
        return buildRequest(url, REQUEST_WITH_XML_HTTP_REQUEST);
    }

    default Request.Builder buildRequest(String url, String requestWith) {
        var httpUrl = HttpUrl.parse(url);
        if (httpUrl == null) throw new NullPointerException();
        return buildRequest(httpUrl, requestWith, httpUrl.scheme() + "://" + httpUrl.host());
    }

    default Request.Builder buildRequest(HttpUrl httpUrl, String requestWith, String origin) {
        return new Request.Builder()
                .url(httpUrl.url())
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0")
                .header("Accept", "*/*")
                .header("Accept-Language", "zh-CN")
                .header("X-Requested-With", requestWith)
                .header("Origin", origin)
                .header("Connection", "keep-alive")
                .header("Sec-Fetch-Dest", "empty")
                .header("Sec-Fetch-Mode", "cors")
                .header("Sec-Fetch-Site", "same-origin")
                .header("Pragma", "no-cache")
                .header("Cache-Control", "no-cache");
    }

    default void doRequestWithJsonResponse(Request request){
        doRequestWithJsonResponse(request, (JavaType) null);
    }

    default <T> T doRequestWithJsonResponse(Request request, Class<T> cls){
        return doRequestWithJsonResponse(request, cls == null ? null : objectMapper().constructType(cls));
    }

    default <T> T doRequestWithJsonResponse(Request request, JavaType javaType){
        try(var response = doRequestWithResponse(request); var body = response.body()) {
            if (body == null) return null;
            if (javaType == null) return null;
            return objectMapper().readValue(body.byteStream(), javaType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    default String doRequestWithPlainText(Request request){
        try(var response = doRequestWithResponse(request); var body = response.body()) {
            if (body == null) return "";
            return body.string();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    default Response doRequestWithResponse(Request request){
        Response response = null;
        try {
            response = httpClient().newCall(request).execute();
            var body = response.body();
            if(!response.isSuccessful()) {
                response.close();
                throw new PlatformException("url=" + request.url().url() + "\tcode=" + response.code() + "\tmsg=" + response.message() + "\tres=" + (body == null ? "" : body.string()));
            }
            return response;
        } catch (IOException e) {
            if (response != null) response.close();
            throw new RuntimeException(e);
        }
    }
}
